Skip to content

✨ [FFL-2857] Feature Flags tab — team filtering + token revocation (stacked PR 4 of 4) - #4932

Merged
kellyw1806 merged 6 commits into
mainfrom
kelly.wang/ffl-2857
Aug 14, 2026
Merged

✨ [FFL-2857] Feature Flags tab — team filtering + token revocation (stacked PR 4 of 4)#4932
kellyw1806 merged 6 commits into
mainfrom
kelly.wang/ffl-2857

Conversation

@kellyw1806

@kellyw1806 kellyw1806 commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Motivation

Stacked on #4912 (flag overrides). Adds team/creator filtering + per-flag descriptions to the Feature Flags tab, plus production OAuth support and token revocation on disconnect.

Stack (review bottom-up)

PR Base What it adds Status
1 of 4 #4913 · FFL-2597 main OAuth sign-in ✅ merged
2 of 4 #4916 · FFL-2858 ffl-2597 catalog browsing ✅ merged
3 of 4 #4912 · FFL-2596 main flag overrides in review
4 of 4 this · FFL-2857 ffl-2596 team filter + token revocation draft

⚠️ Base is kelly.wang/ffl-2596 (#4912) — merge that first. Kept as a draft until #4912 lands; this then retargets to main and gets a quick rebase.

Changes

  • Team & creator filters (server-side): "My feature flags" → created_by=<uuid>; "My teams" → tags=team:<handle>. Identity (user UUID + team handles) comes from /api/v2/current_user + /api/v2/team?filter[me]=true. "My teams" is a checkbox dropdown showing an "N selected" summary.
  • Per-flag description in each row (catalog description attribute), with a "Show more" expander that only appears when the text is actually clamped.
  • Production OAuth: per-site client id (getClientId — staging vs prod); site picker trimmed to US1 + Staging.
  • Token revocation on disconnect (RFC 7009 /oauth2/v1/revoke — revokes the refresh token, clears local tokens either way).
  • Scope-retry: falls back to the required scopes if the OAuth client isn't granted the optional teams_read (via invalid_scope redirect or an authorize page-load failure).

DEMO

Note, we can now choose between datadoghq.com and staging. There are also filters for My Feature Flags and My Teams. Descriptions are fetched as well.

Screen.Recording.2026-08-10.at.1.26.56.PM.mov

Checklist

  • Tested locally
  • Tested on staging
  • Added unit tests for this change
  • Added e2e/integration tests for this change
  • Updated documentation and/or relevant AGENTS.md file

@datadog-datadog-us1-prod

datadog-datadog-us1-prod Bot commented Aug 6, 2026

Copy link
Copy Markdown

Tests

🎉 All green!

🧪 All tests passed
❄️ No new flaky tests detected

🎯 Code Coverage (details)
Patch Coverage: 81.13%
Overall Coverage: 77.25% (+0.04%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 1602ea3 | Docs | Datadog PR Page | Give us feedback!

@kellyw1806
kellyw1806 force-pushed the kelly.wang/ffl-2596 branch 5 times, most recently from c88291e to 2a98437 Compare August 7, 2026 16:44
@kellyw1806
kellyw1806 force-pushed the kelly.wang/ffl-2857 branch from 4c49f6e to 16b1216 Compare August 7, 2026 16:58
@cit-pr-commenter-54b7da

cit-pr-commenter-54b7da Bot commented Aug 7, 2026

Copy link
Copy Markdown

Bundles Sizes Evolution

📦 Bundle Name Base Size Local Size 𝚫 𝚫% Status
Rum 180.44 KiB 180.44 KiB 0 B 0.00%
Rum Profiler 8.43 KiB 8.43 KiB 0 B 0.00%
Rum Recorder 21.12 KiB 21.12 KiB 0 B 0.00%
Logs 57.04 KiB 57.04 KiB 0 B 0.00%
Rum Salesforce N/A 138.47 KiB N/A N/A N/A
Rum Slim 138.47 KiB 138.47 KiB 0 B 0.00%
Worker 22.96 KiB 22.96 KiB 0 B 0.00%
Rum Shopify N/A 200.02 KiB N/A N/A N/A
Rum-shopify Profiler N/A 8.43 KiB N/A N/A N/A
Rum-shopify Recorder N/A 3.72 KiB N/A N/A N/A

@kellyw1806
kellyw1806 force-pushed the kelly.wang/ffl-2596 branch from 2a98437 to da1a176 Compare August 7, 2026 17:26
Base automatically changed from kelly.wang/ffl-2596 to main August 7, 2026 19:14
@kellyw1806
kellyw1806 force-pushed the kelly.wang/ffl-2857 branch 2 times, most recently from e4698ab to c960f4a Compare August 10, 2026 17:25
@kellyw1806
kellyw1806 marked this pull request as ready for review August 10, 2026 17:29
@kellyw1806
kellyw1806 requested a review from a team as a code owner August 10, 2026 17:29

@BeltranBulbarellaDD BeltranBulbarellaDD left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good! Left some comments.

Comment thread developer-extension/src/panel/components/tabs/flagsTab/flagIdentity.ts Outdated
Comment thread developer-extension/src/panel/components/tabs/flagsTab/oauth.ts
Comment thread developer-extension/src/panel/components/tabs/flagsTab/oauth.ts Outdated
Comment thread developer-extension/src/panel/components/tabs/flagsTab/useFlagCatalogView.ts Outdated
Comment thread developer-extension/src/panel/components/tabs/flagsTab/useFlagIdentity.ts Outdated
@kellyw1806
kellyw1806 force-pushed the kelly.wang/ffl-2857 branch from c960f4a to 439df75 Compare August 12, 2026 06:39
chatgpt-codex-connector[bot]

This comment was marked as resolved.

Filter the flag catalog by owning team (teams_read scope + flag identity),
and revoke the OAuth grant at Datadog on disconnect rather than only clearing
local tokens.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@kellyw1806
kellyw1806 force-pushed the kelly.wang/ffl-2857 branch from 439df75 to 850a642 Compare August 12, 2026 15:28

@BeltranBulbarellaDD BeltranBulbarellaDD left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall LGTM! Just some minor edge cases and I think it could be good to merge!

What is the expected behaviour when we are not logged in but we have a local overriden FF? Should it still apply? Cause we have it locally? Because I went to the FF test page and it was in dark mode even though I was unauthenticated.

<Text>Feature Flags</Text>
</Tabs.Tab>
)}
<Tabs.Tab value={PanelTabs.Flags}>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image In the Settings tab when we override a value we show this icon. Would it be possible to do the same here? If on the page we are, we have overriden a FF we could show the icon?

@kellyw1806 kellyw1806 Aug 14, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, was thinking about this but i think it might not be worth the cost? it would need the override state at Panel level, so the extension would read the inspected page on every navigation for every user, including everyone who never opens Flags. That might be a lot of extension-wide overhead? i'm also going to add an alert on the Auth login page so that if there are overrides that exist, it will let you know. maybe that can help as well. having the override remain across disconnect and session restarts is intended, but wanted to add some sort of warning to users

image

Comment thread developer-extension/src/panel/components/tabs/flagsTab/flagsTab.tsx Outdated
- show an override notice on the connect screen so overrides left on the
  page are visible before authenticating
- report success/failure inline on the manual override form, and note that
  re-applying an existing key replaces its value
- stop uppercasing the site badge (datad0g vs datadoghq differ by one glyph)
  and move Disconnect to the far end of the row
- condense inline comments into function-level docs

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
chatgpt-codex-connector[bot]

This comment was marked as resolved.

The connect screen is dd-privacy-allow, so anything rendered there is
unmasked in the extension's own Session Replay. Only a count renders today,
but flag keys are customer data — mask the alert so adding them later can't
leak silently.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
chatgpt-codex-connector[bot]

This comment was marked as resolved.

kellyw1806 and others added 2 commits August 14, 2026 00:48
Cut comments that restated the code they sat on, condensed multi-line
explanations to their load-bearing sentence, and moved component-level
prose into JSDoc.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Success was derived from the stored value alone, so submitting a NUMERIC 1
over a stored INTEGER 1 matched immediately. If the write then failed, the
form showed success and hid the error for a change that never landed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@BeltranBulbarellaDD BeltranBulbarellaDD left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor nits but LGTM!

teamHandles: string[]
/** True when the team lookup was refused because the user lacks permission to read teams. */
teamsForbidden: boolean
/** True when the team lookup failed for another reason (network/server), distinct from an empty membership. */

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel the comments do not add any value here.

borderBottom: '1px solid var(--mantine-color-gray-1)',
backgroundColor: overridden ? 'var(--mantine-color-violet-0)' : undefined,
borderBottom: '1px solid var(--mantine-color-default-border)',
// Mantine's scheme-aware subtle tint (the one variant="light" uses), not a saturated fill.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need I believe

}, [description, expanded])

return (
// Slightly more separation than the name↔key gap, so the row reads as "title/key" then "description".

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't think it adds value

export interface CatalogFlag {
key: string
name: string
/** Free-text description authored in the Datadog UI. Empty when the flag has none. */

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment is redundant i think?

tagFilter: string[]
/** Team handles for the "My teams" filter, sent as `tags=team:<handle>`. */
teamFilter: string[]
/** The signed-in user's UUID when "My feature flags" is on, else null. Sent as `created_by`. */

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is repeated above twice.


/**
* Revokes the refresh token — the renewable part of the grant. The access token is left to expire
* (RFC 7009 only *recommends* cascading revocation, so we don't rely on it) and is dropped locally

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't get this line. Should we have a link to the RFC? or remove it?

const CATALOG_PAGE_SIZE = 20
// Wait out a typing burst before sending a search to the server, so we don't fire a request per
// keystroke. Short enough to still feel responsive.
// Long enough to wait out a typing burst, short enough to still feel responsive.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need, we know what a debounce is.

Remove field docs that repeated their own names or the enclosing interface
doc, and replace the opaque RFC 7009 aside on tryRevokeGrant with a plain
explanation plus a link on revokeAndClearTokens.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@kellyw1806
kellyw1806 merged commit 3a89cc2 into main Aug 14, 2026
31 checks passed
@kellyw1806
kellyw1806 deleted the kelly.wang/ffl-2857 branch August 14, 2026 15:51
@github-actions github-actions Bot locked and limited conversation to collaborators Aug 14, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants